package com.yonyou.hxjy.service.dingtalk.Impl.dintalkgetImpl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.hxjy.enums.DingtalkConstant;
import com.yonyou.hxjy.service.dingtalk.DingtalkAccessTokenGetService;
import com.yonyou.hxjy.service.dingtalk.DingtalkProcessInstanceGet;
import com.yonyou.hxjy.service.dingtalk.Impl.DealProcessInstanceData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class DingTalkProcessInstanceGetImpl implements DingtalkProcessInstanceGet {

    @Autowired
    private DingtalkAccessTokenGetService dingtalkAccessTokenGetService;

    @Autowired
    private DealProcessInstanceData dealProcessInstanceData;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    private final ExecutorService executorService = Executors.newFixedThreadPool(5); // 开启线程数

    @Override
    public List<String> getProcessInstanceId(Map<String, Object> param,String businessType) {

        String token = dingtalkAccessTokenGetService.getAppToken("001");
        String url = DingtalkConstant.GET_PROCESS_INSTANCE_IDS;

        System.out.println(param);
        // 创建 HttpHeaders 对象并设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");       // 示例：设置内容类型
        headers.set("x-acs-dingtalk-access-token", token);     // 示例：添加自定义头

        // 如果有请求体，可以在这里创建（如果没有请求体，传入 null）
        String requestBody = null;
        JSONObject jsonObject = null;
        //审批实例id列表
        List<String> instanceId = new ArrayList<>();
        //构建请求体
        HttpEntity<String> requestEntity;
        //获取响应数据
        ResponseEntity<String> response;
        //获取响应数据中的id列表
        JSONArray jsonArray;

        //更新分页游标循环查出分页数据
        while (true){
            try {
                requestBody = objectMapper.writeValueAsString(param);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }

            // 创建 HttpEntity 对象，包含请求头和请求体
            requestEntity = new HttpEntity<>(requestBody, headers);

            // 发送请求并获取响应
            response = restTemplate.exchange(
                    url,                      // 请求 URL
                    HttpMethod.POST,          // HTTP 方法
                    requestEntity,            // 包含请求头和请求体的 HttpEntity
                    String.class              // 响应数据的类型
            );

            jsonObject = JSONUtil.parseObj(response.getBody()); //获取返回结果

            jsonArray = jsonObject.getJSONObject("result").getJSONArray("list");
            if (jsonArray != null && !jsonArray.isEmpty()) {
                // 将 JSONArray 的数据添加到 List<String>

                for (int i = 0; i < jsonArray.size(); i++) {
                    // 从 JSONArray 中获取每个元素并添加到 List 中
                    instanceId.add(jsonArray.getStr(i));
                }
            }
            if (jsonObject.getJSONObject("result").getStr("nextToken")==null){
                break;
            }else {
                System.out.println("新的分页游标的值:"+jsonObject.getJSONObject("result").getStr("nextToken"));
                //将分页游标赋新值继续循环查询
                param.put("nextToken", jsonObject.getJSONObject("result").getStr("nextToken"));
            }
            //System.out.println(jsonObject.toString());
        }
        //保存到本地
        dealProcessInstanceData.saveProcessInstanceId(instanceId,businessType);
        return instanceId;
    }

    @Override
    public Map<String,Object> getProcessInstanceDetails(String businessType) {
        //获取未保存的单据
        List<String> processInstanceIdList = dealProcessInstanceData.getProcessInstanceList(businessType);
        String token = dingtalkAccessTokenGetService.getAppToken("001");
        String url = DingtalkConstant.GET_PROCESS_INSTANCE_DETAILS;
        //保存全部实例
        List<JSONObject> jsonObjectList = new ArrayList<>();
        Map<String,Object> param = new HashMap<>();
        //System.out.println(processInstanceIds);
        // 创建 HttpHeaders 对象并设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        headers.set("x-acs-dingtalk-access-token", token);

        // 创建 HttpEntity 对象
        HttpEntity<String> requestEntity = new HttpEntity<>(headers);

        if (processInstanceIdList == null && processInstanceIdList.isEmpty()) {
            return (Map<String, Object>) Collections.emptyList();
        }
        // 使用 CompletableFuture 并发执行所有请求
        List<CompletableFuture<JSONObject>> futureList = processInstanceIdList.stream()
                .map(id -> CompletableFuture.supplyAsync(() -> fetchProcessInstance(url, requestEntity, id), executorService))
                .collect(Collectors.toList());
        // 等待所有请求完成，并收集结果
        for (CompletableFuture<JSONObject> future : futureList) {
            try {
                JSONObject result = future.get(); // 可设置超时时间
                if (result != null) {
                    jsonObjectList.add(result);
                }
            } catch (InterruptedException | ExecutionException e) {
                // 处理异常（可记录日志、跳过）
                e.printStackTrace();
            }
        }
//        for (int i =0; i<processInstanceIds.size();i++){
//            // 发送 GET 请求并获取完整的响应
//            responseEntity = restTemplate.exchange(
//                    url,                      // 请求 URL
//                    HttpMethod.GET,           // HTTP 方法
//                    requestEntity,            // 包含请求头的 HttpEntity
//                    String.class,             // 响应数据类型
//                    processInstanceIds.get(i)  // 查询参数值
//            );
//            //解析响应体为jsonObject对象
//            jsonObject = JSONUtil.parseObj(responseEntity.getBody());
//            jsonObjectList.add(jsonObject);
//        }
        param.put("jsonObjectList",jsonObjectList);
        param.put("processInstanceIdList",processInstanceIdList);
        return param;
    }
    // 每个线程中执行的请求逻辑
    private JSONObject fetchProcessInstance(String url, HttpEntity<String> requestEntity, String processInstanceId) {
        try {
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    String.class,
                    processInstanceId
            );
            JSONObject jsonObject = JSONUtil.parseObj(responseEntity.getBody());
            JSONObject result = jsonObject.getJSONObject("result");
            List<JSONObject> tasks = result.getJSONArray("tasks").toList(JSONObject.class);
            Boolean isTb=false;
            for(JSONObject task:tasks){
                //17127137219696885 李嫒   胡东梅-1718785327792823
                if((task.getStr("userId").equals("17127137219696885") || task.getStr("userId").equals("1718785327792823")|| task.getStr("userId").equals("2139572709999804")) && task.getStr("status").equals("RUNNING")){
                    isTb=true;
                    break;
                }
            }
            if(isTb){
                return JSONUtil.parseObj(responseEntity.getBody());
            }else{
                return null;
            }
//            return JSONUtil.parseObj(responseEntity.getBody());
        } catch (Exception e) {
            // 可记录失败的日志或返回空对象等
            System.err.println("请求失败: " + processInstanceId + ", 错误: " + e.getMessage());
            return null;
        }
    }
    @PreDestroy
    public void shutdownExecutor() {
        executorService.shutdownNow();
    }

}
